package edu.cuit.avatar.factory;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 工厂模式:创建型设计模式,提供了一种创建对象的最佳方式,无需对创建对象的创建逻辑暴露给客户端
 *      1.简单工厂模式
 *      2.工厂方法模式: 提供了工厂的接口，让类把实例化延迟到子类
 *      3.抽象工厂模式: 创建一系列相关或相互依赖对象的接口,而无需指定具体的类
 * @author <a href="mailto:1020zhaodan@163.com">Adan</a>
 * @version 1.0
 * @date 2025/7/19 8:58
 */
public class InstanceFactory {
    public static final Map<String, Object> cache = new HashMap<>();

    private InstanceFactory(){

    }

    static{
        try {
            //1.读取properties配置文件
            Properties prop = new Properties();
            //使用类加载器加载资源文件(从classpath下进行加载)
            var input = InstanceFactory.class.getClassLoader().getResourceAsStream("container.properties");
            //将properties文件中所有的key-value加载进Properties
            prop.load(input);
            //读取properties中所有的key,加载对应的value,创建其实例,存入缓存
            for (Object key : prop.keySet()) {
                String value = prop.getProperty(key.toString());
                var instance = Class.forName(value).getDeclaredConstructor().newInstance();
                cache.put(key.toString(), instance);
            }
        } catch (IOException | ClassNotFoundException
                 | InvocationTargetException | InstantiationException
                 | IllegalAccessException | NoSuchMethodException e) {
            //todo 记录异常日志
            throw new RuntimeException(e);
        }
    }
    /**
     * 工厂方法:根据实例名称创建指定类型的实例对象
     * @param instanceName 实例名称
     * @return 实例
     * @param <T> 类型化参数
     */
    public static <T> T create(String instanceName){
        return (T)cache.get(instanceName);
    }
}
